package com.bsoft.gol.hcs.satisfyStatic.service.impl;

import ctd.account.UserRoleToken;
import ctd.controller.exception.ControllerException;
import ctd.mvc.upload.FileMetaEntity;
import ctd.mvc.upload.FileService;
import ctd.persistence.annotation.DAOTransaction;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.BeanUtils;
import ctd.util.annotation.RpcService;
import com.bsoft.gol.hcs.enumcase.StatisticExtraTypeEnum;
import org.atag.dao.model.SimplePageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.bsoft.gol.hcs.satisfyStatic.bean.qo.*;
import com.bsoft.gol.hcs.satisfyStatic.bean.vo.*;
import com.bsoft.gol.hcs.satisfyStatic.dao.OdsSatisfyStatisticExtraDAO;
import com.bsoft.gol.hcs.satisfyStatic.dao.OdsSatisfyStatisticExtraDetailDAO;
import com.bsoft.gol.hcs.satisfyStatic.dao.OdsSatisfyStatisticSettingDAO;
import com.bsoft.gol.hcs.satisfyStatic.entity.OdsSatisfyStatisticExtra;
import com.bsoft.gol.hcs.satisfyStatic.entity.OdsSatisfyStatisticExtraDetail;
import com.bsoft.gol.hcs.satisfyStatic.entity.OdsSatisfyStatisticSetting;
import com.bsoft.gol.hcs.satisfyStatic.service.ISatisfySurveyStatisticService;
import com.bsoft.gol.hcs.utils.CommonUtils;
import com.bsoft.gol.hcs.utils.DateUtils;

import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 满意度统计
 * Created by ChenJij on 2022/7/26.
 */
@SsdevService("satisfySurveyStatisticService")
public class SatisfySurveyStatisticServiceImpl implements ISatisfySurveyStatisticService {
    private static final Logger LOGGER = LoggerFactory.getLogger(SatisfySurveyStatisticServiceImpl.class);
    @Autowired
    private OdsSatisfyStatisticSettingDAO odsSatisfyStatisticSettingDAO;
    @Autowired
    private OdsSatisfyStatisticExtraDetailDAO odsSatisfyStatisticExtraDetailDAO;
    @Autowired
    private OdsSatisfyStatisticExtraDAO odsSatisfyStatisticExtraDAO;


    /**
     * @param qo
     * @description: 查询报表配置列表
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:41
     */
    @Override
    @RpcService
    public List<QuerySatisfyStatisticSettingListVo> querySatisfyStatisticSettingList(QuerySatisfyStatisticSettingListQo qo) throws ControllerException {
        try {
            if(CommonUtils.isEmpty(qo.getTenantId())){
                throw new ControllerException("租户id不能为空");
            }
            List<QuerySatisfyStatisticSettingListVo> odsSatisfyStatisticSettings = odsSatisfyStatisticSettingDAO.queryAllByTenantId(qo.getTenantId());
            return odsSatisfyStatisticSettings;
        }catch (ControllerException e){
            throw new ControllerException(e.getMessage());
        }catch (Exception e){
            LOGGER.error("查询报表配置列表失败:" + e.getMessage());
            throw new ControllerException("查询报表配置列表失败");
        }
    }

    /**
     * @param qo
     * @description: 查询报表配置详情
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:43
     */
    @Override
    @RpcService
    public GetSatisfyStatisticSettingDetailVo getSatisfyStatisticSettingDetail(GetSatisfyStatisticSettingDetailQo qo) throws ControllerException {
        try {
            OdsSatisfyStatisticSetting existSetting;
            if(CommonUtils.isNotEmpty(qo.getSettingId())){
                //查询满意度调查统计报表配置
                existSetting = odsSatisfyStatisticSettingDAO.get(qo.getSettingId());

                if(null == existSetting){
                    throw new ControllerException("该配置不存在");
                }
                GetSatisfyStatisticSettingDetailVo detailVo = new GetSatisfyStatisticSettingDetailVo();
                detailVo.setSettingId(existSetting.getSettingId());
                detailVo.setSettingName(existSetting.getSettingName());
                detailVo.setQuestionnaireId(existSetting.getQuestionnaireId());
                detailVo.setQuestionnaireName(existSetting.getQuestionnaireName());
                List<GetSatisfyStatisticSettingDetailVo.StatisticExtraList> dimensionList  = new ArrayList<>();
                List<GetSatisfyStatisticSettingDetailVo.StatisticExtraList> typeList  = new ArrayList<>();
                detailVo.setDimensionList(dimensionList);
                detailVo.setTypeList(typeList);

                //查询满意度调查统计报表管理拓展属性列表
                List<OdsSatisfyStatisticExtra> odsSatisfyStatisticExtras = odsSatisfyStatisticExtraDAO.queryBySettingId(qo.getSettingId());
                if(CommonUtils.isNotEmpty(odsSatisfyStatisticExtras)){
                    GetSatisfyStatisticSettingDetailVo.StatisticExtraList statisticExtra;
                    List<GetSatisfyStatisticSettingDetailVo.StatisticExtraDetailList> statisticExtraDetailList;
                    GetSatisfyStatisticSettingDetailVo.StatisticExtraDetailList detail;

                    for (OdsSatisfyStatisticExtra odsSatisfyStatisticExtra : odsSatisfyStatisticExtras) {
                        statisticExtra = new GetSatisfyStatisticSettingDetailVo.StatisticExtraList();
                        BeanUtils.copy(odsSatisfyStatisticExtra,statisticExtra);
                        statisticExtraDetailList = new ArrayList<>();
                        statisticExtra.setStatisticExtraDetailList(statisticExtraDetailList);
                        if(StatisticExtraTypeEnum.WD.getType().equals(odsSatisfyStatisticExtra.getStatisticExtraType())){
                            dimensionList.add(statisticExtra);
                        }else if(StatisticExtraTypeEnum.WTSX.getType().equals(odsSatisfyStatisticExtra.getStatisticExtraType())){
                            typeList.add(statisticExtra);
                        }

                        //查询满意度调查统计报表管理拓展属性详情列表
                        List<OdsSatisfyStatisticExtraDetail> extraDetails = odsSatisfyStatisticExtraDetailDAO.queryByStatisticExtraId(odsSatisfyStatisticExtra.getStatisticExtraId());
                        if(CommonUtils.isNotEmpty(extraDetails)){
                            for (OdsSatisfyStatisticExtraDetail extraDetail : extraDetails) {
                                detail = new GetSatisfyStatisticSettingDetailVo.StatisticExtraDetailList();
                                BeanUtils.copy(extraDetail,detail);
                                statisticExtraDetailList.add(detail);
                            }
                        }
                    }
                }
                return detailVo;
            }else {
                throw new ControllerException("settingId不能为空");
            }
        }catch (ControllerException e){
            throw new ControllerException(e.getMessage());
        }catch (Exception e){
            LOGGER.error("查询报表配置详情失败:" + e.getMessage());
            throw new ControllerException("查询报表配置详情失败");
        }
    }

    /**
     * @param qo
     * @description: 删除查询报表配置
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:43
     */
    @Override
    @RpcService
    public void deleteSatisfyStatisticSetting(GetSatisfyStatisticSettingDetailQo qo) throws ControllerException {
        try {
            //删除满意度调查统计报表配置
            odsSatisfyStatisticSettingDAO.remove(qo.getSettingId());
            //删除满意度调查统计报表管理拓展属性
            odsSatisfyStatisticExtraDAO.deleteAllBySettingId(qo.getSettingId());
            //删除满意度调查统计报表管理拓展属性详情
            odsSatisfyStatisticExtraDetailDAO.deleteAllBySettingId(qo.getSettingId());
        } catch (Exception e) {
            LOGGER.error("删除查询报表配置失败:" + e.getMessage());
            throw new ControllerException("删除查询报表配置失败");
        }
    }

    /**
     * @param qo
     * @description: 新增、修改报表配置
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:45
     */
    @Override
    @RpcService
    @DAOTransaction
    public SaveSatisfyStatisticSettingVo saveSatisfyStatisticSetting(SaveSatisfyStatisticSettingQo qo) throws ControllerException {
        SaveSatisfyStatisticSettingVo saveSatisfyStatisticSettingVo;
        try {
            //校验报表的维度及问题属性
            validateSaveSatisfyStatisticSettingQo(qo);
            OdsSatisfyStatisticSetting existSetting;
            if(CommonUtils.isNotEmpty(qo.getSettingId())){
                existSetting = odsSatisfyStatisticSettingDAO.get(qo.getSettingId());

                if(null == existSetting){
                    throw new ControllerException("该配置不存在");
                }
                //删除满意度调查统计报表管理拓展属性
                odsSatisfyStatisticExtraDAO.deleteAllBySettingId(qo.getSettingId());
                //删除满意度调查统计报表管理拓展属性详情
                odsSatisfyStatisticExtraDetailDAO.deleteAllBySettingId(qo.getSettingId());
            }else {
                String tenantId = UserRoleToken.getCurrentTenantId();
                List<QuerySatisfyStatisticSettingListVo> settingVoList = odsSatisfyStatisticSettingDAO.queryAllByTenantId(tenantId);
                if(CommonUtils.isNotEmpty(settingVoList) && settingVoList.size()>=30){
                    throw new ControllerException("维护报表数目上限为30,已达上限");
                }
                existSetting = new OdsSatisfyStatisticSetting();
                existSetting.setTenantId(tenantId);
                existSetting.setCreateTime(new Date());
            }
            existSetting.setSettingName(qo.getSettingName());
            existSetting.setQuestionnaireId(qo.getQuestionnaireId());
            existSetting.setQuestionnaireName(qo.getQuestionnaireName());
            existSetting.setModifyTime(new Date());

            if(CommonUtils.isNotEmpty(existSetting.getSettingId())){
                odsSatisfyStatisticSettingDAO.update(existSetting);
            }else {
                existSetting.setSettingId(UUID.randomUUID().toString());
                odsSatisfyStatisticSettingDAO.save(existSetting);
            }

            OdsSatisfyStatisticExtra odsSatisfyStatisticExtra;
            OdsSatisfyStatisticExtraDetail odsSatisfyStatisticExtraDetail;

            List<SaveSatisfyStatisticSettingQo.StatisticExtraList> list = new ArrayList<>();
            list.addAll(qo.getDimensionList());
            list.addAll(qo.getTypeList());
            for (SaveSatisfyStatisticSettingQo.StatisticExtraList statisticExtraList : list) {
                odsSatisfyStatisticExtra = new OdsSatisfyStatisticExtra();
                odsSatisfyStatisticExtra.setStatisticExtraId(UUID.randomUUID().toString());
                odsSatisfyStatisticExtra.setSettingId(existSetting.getSettingId());
                odsSatisfyStatisticExtra.setStatisticExtraType(statisticExtraList.getStatisticExtraType());
                odsSatisfyStatisticExtra.setStatisticExtraTypeName(statisticExtraList.getStatisticExtraTypeName());
                odsSatisfyStatisticExtra.setSort(statisticExtraList.getSort());
                odsSatisfyStatisticExtraDAO.save(odsSatisfyStatisticExtra);

                List<SaveSatisfyStatisticSettingQo.StatisticExtraDetailList> statisticExtraDetailList = statisticExtraList.getStatisticExtraDetailList();
                for (SaveSatisfyStatisticSettingQo.StatisticExtraDetailList extraDetailList : statisticExtraDetailList) {
                    odsSatisfyStatisticExtraDetail = new OdsSatisfyStatisticExtraDetail();
                    odsSatisfyStatisticExtraDetail.setExtraDetailId(UUID.randomUUID().toString());
                    odsSatisfyStatisticExtraDetail.setSettingId(existSetting.getSettingId());
                    odsSatisfyStatisticExtraDetail.setStatisticExtraId(odsSatisfyStatisticExtra.getStatisticExtraId());
                    odsSatisfyStatisticExtraDetail.setTitleId(extraDetailList.getTitleId());
                    odsSatisfyStatisticExtraDetail.setTitleName(extraDetailList.getTitleName());
                    odsSatisfyStatisticExtraDetail.setSort(extraDetailList.getSort());
                    odsSatisfyStatisticExtraDetailDAO.save(odsSatisfyStatisticExtraDetail);
                }
            }
            saveSatisfyStatisticSettingVo = new SaveSatisfyStatisticSettingVo();
            saveSatisfyStatisticSettingVo.setSettingId(existSetting.getSettingId());
        }catch (ControllerException e){
            throw new ControllerException(e.getMessage());
        }catch (Exception e){
            e.printStackTrace();
            LOGGER.error("新增、修改报表配置失败:" + e.getMessage());
            throw new ControllerException("新增、修改报表配置失败");
        }

        return saveSatisfyStatisticSettingVo;
    }

    /**
     * @description: 校验报表的维度及问题属性
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/27 11:13
     * @param: qo
     * @return: void
     */
    private void validateSaveSatisfyStatisticSettingQo(SaveSatisfyStatisticSettingQo qo) throws ControllerException {
        if(CommonUtils.isEmpty(qo.getDimensionList())){
            throw new ControllerException("报表的维度不能为空");
        }
        if(CommonUtils.isEmpty(qo.getTypeList())){
            throw new ControllerException("报表的问题属性不能为空");
        }
        if(CommonUtils.isEmpty(qo.getSettingName())){
            throw new ControllerException("报表的名称不能为空");
        }
        if(qo.getSettingName().length()>50){
            throw new ControllerException("报表的名称不能超过50");
        }
        //维度名称集合
        Set<String> wdNameSet = new HashSet<>();
        //问题属性及分类名称集合
        Set<String> sxNameSet = new HashSet<>();

        for (int i = 0; i < qo.getDimensionList().size(); i++) {
            SaveSatisfyStatisticSettingQo.StatisticExtraList statisticExtraList = qo.getDimensionList().get(i);
            if(CommonUtils.isEmpty(statisticExtraList.getStatisticExtraType())){
                throw new ControllerException("报表的维度类型不能为空");
            }
            if(CommonUtils.isEmpty(statisticExtraList.getStatisticExtraDetailList())){
                throw new ControllerException("报表的维度的题目不能为空");
            }
            if(CommonUtils.isEmpty(statisticExtraList.getStatisticExtraTypeName())){
                throw new ControllerException("报表的维度名称不能为空");
            }
            if(statisticExtraList.getStatisticExtraTypeName().length()>50){
                throw new ControllerException("报表的维度名称不能超过50");
            }
            if(wdNameSet.contains(statisticExtraList.getStatisticExtraTypeName())){
                throw new ControllerException("报表的维度名称不能重复");
            }
            wdNameSet.add(statisticExtraList.getStatisticExtraTypeName());
            statisticExtraList.setSort(i);
        }

        for (int i = 0; i < qo.getTypeList().size(); i++) {
            SaveSatisfyStatisticSettingQo.StatisticExtraList statisticExtraList = qo.getTypeList().get(i);
            if(CommonUtils.isEmpty(statisticExtraList.getStatisticExtraType())){
                throw new ControllerException("报表的问题属性类型不能为空");
            }
            if(CommonUtils.isEmpty(statisticExtraList.getStatisticExtraDetailList())){
                throw new ControllerException("报表的问题属性及分类的题目不能为空");
            }
            if(CommonUtils.isEmpty(statisticExtraList.getStatisticExtraTypeName())){
                throw new ControllerException("报表的问题属性及分类名称不能为空");
            }
            if(statisticExtraList.getStatisticExtraTypeName().length()>50){
                throw new ControllerException("报表的问题属性及分类名称不能超过50");
            }
            if(sxNameSet.contains(statisticExtraList.getStatisticExtraTypeName())){
                throw new ControllerException("报表的问题属性及分类名称不能重复");
            }
            sxNameSet.add(statisticExtraList.getStatisticExtraTypeName());
            statisticExtraList.setSort(i);
        }

        if(qo.getDimensionList().size()==0){
            throw new ControllerException("报表的维度至少要维护1个");
        }
        if(qo.getDimensionList().size()>12){
            throw new ControllerException("报表的维度上限是12个,已超过上限");
        }
        if(qo.getTypeList().size()==0){
            throw new ControllerException("报表的问题属性及分类至少要维护1个");
        }
        if(qo.getTypeList().size()>12){
            throw new ControllerException("报表的问题属性及分类上限是12个,已超过上限");
        }
    }

    /**
     * @param qo
     * @description: 查询报表维度列表
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:45
     */
    @Override
    @RpcService
    public List<QueryStatisticExtraIdListVo> queryStatisticExtraIdList(QueryStatisticExtraIdListQo qo) throws ControllerException {
//        try {
//
//        }catch (ControllerException e){
//            throw new ControllerException(e.getMessage());
//        }catch (Exception e){
//            LOGGER.error("查询报表维度列表失败:" + e.getMessage());
//            throw new ControllerException("查询报表维度列表失败");
//        }
        return null;
    }

    /**
     * @param qo
     * @description: 查询满意度问卷统计列表标题
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:45
     */
    @Override
    @RpcService
    public QuerySatisfySurveyStatisticListVo querySatisfySurveyStatisticTitleList(QuerySatisfySurveyStatisticListQo qo) throws ControllerException {
        List<OdsSatisfyStatisticExtra> odsSatisfyStatisticExtras = odsSatisfyStatisticExtraDAO.queryBySettingIdAndStatisticExtraType(qo.getSettingId(),StatisticExtraTypeEnum.WTSX.getType());
        QuerySatisfySurveyStatisticListVo classifyScoreTitle = new QuerySatisfySurveyStatisticListVo();
        classifyScoreTitle.setSort("序号");
        classifyScoreTitle.setProportion("占比（%）");
        classifyScoreTitle.setSurveyPersonNumber("调查人次");
        classifyScoreTitle.setPlanNumber("计划调查");
        classifyScoreTitle.setAfterHosNumber("临时调查");
        classifyScoreTitle.setScanCodeNumber("自主扫码调查");
        classifyScoreTitle.setAbnormalNumber("异常数");
        classifyScoreTitle.setAbnormalProportion("异常占比（%）");
        if(!"0".equals(qo.getStatisticExtraId())){
            OdsSatisfyStatisticExtra extra = odsSatisfyStatisticExtraDAO.get(qo.getStatisticExtraId());
            if(null != extra) {
                classifyScoreTitle.setTypeName(extra.getStatisticExtraTypeName());
            }

            int sort = 1;
            Method method;
            for (OdsSatisfyStatisticExtra odsSatisfyStatisticExtra : odsSatisfyStatisticExtras) {
                try {
                    method = classifyScoreTitle.getClass().getDeclaredMethod("setScore" + sort, String.class);
                    method.setAccessible(true);
                    method.invoke(classifyScoreTitle, odsSatisfyStatisticExtra.getStatisticExtraTypeName());

                    method = classifyScoreTitle.getClass().getDeclaredMethod("setStandardDeviationScore" + sort, String.class);
                    method.setAccessible(true);
                    method.invoke(classifyScoreTitle, "s-"+odsSatisfyStatisticExtra.getStatisticExtraTypeName().substring(0,1));
                } catch (Exception e) {
                    throw new ControllerException("初始化统计报表标题失败");
                }
                sort++;
            }
        }else {
            classifyScoreTitle.setTypeName("内容");
            classifyScoreTitle.setScore1("本次得分");
            classifyScoreTitle.setStandardDeviationScore1("标准差");
            classifyScoreTitle.setMedian("中位数");
            classifyScoreTitle.setMaxScore("最大值");
            classifyScoreTitle.setMinScore("最小值");
        }




        return classifyScoreTitle;
    }

    /**
     * @param qo
     * @description: 查询满意度问卷统计标题列表
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:45
     */
    @RpcService
    public List<String> queryTitleStringList(QuerySatisfySurveyStatisticListQo qo) throws ControllerException {
        List<OdsSatisfyStatisticExtra> odsSatisfyStatisticExtras = odsSatisfyStatisticExtraDAO.queryBySettingIdAndStatisticExtraType(qo.getSettingId(),StatisticExtraTypeEnum.WTSX.getType());
        List<String> titleList = new ArrayList<>();
        titleList.add("序号");
        if(!"0".equals(qo.getStatisticExtraId())){
            OdsSatisfyStatisticExtra extra = odsSatisfyStatisticExtraDAO.get(qo.getStatisticExtraId());
            if(extra != null) {
                titleList.add(extra.getStatisticExtraTypeName());
            }else {
                titleList.add("");
            }
        }else {
            titleList.add("内容");
        }
        titleList.add("占比（%）");
        titleList.add("调查人次");
        titleList.add("计划调查");
        titleList.add("临时调查");
        titleList.add("自主扫码调查");
        titleList.add("异常数");
        titleList.add("异常占比（%）");
        if(!"0".equals(qo.getStatisticExtraId())){
            for (OdsSatisfyStatisticExtra odsSatisfyStatisticExtra : odsSatisfyStatisticExtras) {
                titleList.add(odsSatisfyStatisticExtra.getStatisticExtraTypeName());
                titleList.add("s-"+odsSatisfyStatisticExtra.getStatisticExtraTypeName().substring(0,1));
            }
        }else {
            titleList.add("本次得分");
            titleList.add("标准差");
            titleList.add("中位数");
            titleList.add("最大值");
            titleList.add("最小值");
        }

        return titleList;
    }

    /**
     * @param qo
     * @description: 查询满意度问卷统计列表
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/26 10:45
     */
    @Override
    @RpcService
    public SimplePageInfo<QuerySatisfySurveyStatisticListVo> querySatisfySurveyStatisticList(QuerySatisfySurveyStatisticListQo qo) throws ControllerException {
        //分页查询控件里面有排除了空字符串的情况，所以前端那边传了空字符串，这边把机构代码设为null,使查询结果返回空
        if("".equals(qo.getOrganizationId())){
            qo.setOrganizationId("null");
        }

        if(CommonUtils.isNotEmpty(qo.getEndDate())){
            qo.setEndDate(DateUtils.addDate(qo.getEndDate(),"yyyy-MM-dd",1));
        }

        try {
            //维度id不为0，查询条件加上titleId
            if(CommonUtils.isNotEmpty(qo.getStatisticExtraId()) && !"0".equals(qo.getStatisticExtraId())){
                List<OdsSatisfyStatisticExtraDetail> details = odsSatisfyStatisticExtraDetailDAO.queryByStatisticExtraId(qo.getStatisticExtraId());
                if(CommonUtils.isNotEmpty(details)){
                    qo.setTitleId(details.get(0).getTitleId());
                }
            }

            SimplePageInfo<QuerySatisfySurveyStatisticListVo> simplePageInfo = null;
            QuerySatisfySurveyStatisticListVo satisfySurveyStatisticTotal;
            if(!"0".equals(qo.getStatisticExtraId())){
                simplePageInfo = odsSatisfyStatisticSettingDAO.querySatisfySurveyStatisticList(qo);
                satisfySurveyStatisticTotal = odsSatisfyStatisticSettingDAO.getSatisfySurveyStatisticTotal(qo);
            }else {
                simplePageInfo = odsSatisfyStatisticSettingDAO.querySatisfySurveyStatisticListByTitle(qo);
                satisfySurveyStatisticTotal = odsSatisfyStatisticSettingDAO.getSatisfySurveyStatisticTotalByTitle(qo);
            }
            if(null == satisfySurveyStatisticTotal){
                satisfySurveyStatisticTotal = new QuerySatisfySurveyStatisticListVo();
            }
            satisfySurveyStatisticTotal.setSort("合计");


            List<Map<String,List<QuerySatisfySurveyStatisticListVo.ClassifyScoreList>>> mapList = new ArrayList<>();
            Map<String,QuerySatisfySurveyStatisticListVo.ClassifyScoreList> titleOptionIdMap = new HashMap();


            if(!"0".equals(qo.getStatisticExtraId())){
                List<OdsSatisfyStatisticExtra> odsSatisfyStatisticExtras = odsSatisfyStatisticExtraDAO.queryBySettingIdAndStatisticExtraType(qo.getSettingId(),StatisticExtraTypeEnum.WTSX.getType());
                if(CommonUtils.isNotEmpty(odsSatisfyStatisticExtras)){
                    int sort = 1;

                    for (OdsSatisfyStatisticExtra odsSatisfyStatisticExtra : odsSatisfyStatisticExtras) {
                        Map<String,List<QuerySatisfySurveyStatisticListVo.ClassifyScoreList>> optionIdMap = new HashMap();

                        //查询题目列表
                        List<String> titleIdList = odsSatisfyStatisticExtraDetailDAO.queryTitleIdListByStatisticExtraId(odsSatisfyStatisticExtra.getStatisticExtraId());
                        qo.setTitleIdList(titleIdList);

                        //查询问卷统计分数列表
                        List<QuerySatisfySurveyStatisticListVo.ClassifyScoreList> classifyScoreLists = odsSatisfyStatisticSettingDAO.queryClassifyScoreList(qo);

                        if (CommonUtils.isNotEmpty(classifyScoreLists)) {
                            BigDecimal totalClassifyScore = BigDecimal.ZERO;
                            BigDecimal totalStandardDeviationScore = BigDecimal.ZERO;
                            for (QuerySatisfySurveyStatisticListVo.ClassifyScoreList classifyScore : classifyScoreLists) {
                                BigDecimal score = new BigDecimal(classifyScore.getClassifyScore());
                                BigDecimal standardDeviationScore = new BigDecimal(classifyScore.getStandardDeviationScore());
                                classifyScore.setClassifyScore(score.setScale(2,RoundingMode.HALF_UP).toString());
                                classifyScore.setStandardDeviationScore(standardDeviationScore.setScale(2,RoundingMode.HALF_UP).toString());

                                totalClassifyScore = totalClassifyScore.add(score);
                                totalStandardDeviationScore = totalStandardDeviationScore.add(standardDeviationScore);

                                classifyScore.setSort(sort);
                                List<QuerySatisfySurveyStatisticListVo.ClassifyScoreList> scoreLists = optionIdMap.get(classifyScore.getOptionId());
                                if (null == scoreLists) {
                                    scoreLists = new ArrayList<>();
                                }
                                scoreLists.add(classifyScore);
                                optionIdMap.put(classifyScore.getOptionId(), scoreLists);
                            }
                            BigDecimal avgClassifyScore = totalClassifyScore.divide(new BigDecimal(classifyScoreLists.size()),2,RoundingMode.HALF_UP);
                            BigDecimal avgStandardDeviationScore = totalStandardDeviationScore.divide(new BigDecimal(classifyScoreLists.size()),2,RoundingMode.HALF_UP);

                            Method method;
                            try {
                                method = satisfySurveyStatisticTotal.getClass().getDeclaredMethod("setScore" + sort, String.class);
                                method.setAccessible(true);
                                method.invoke(satisfySurveyStatisticTotal, avgClassifyScore.toString());

                                method = satisfySurveyStatisticTotal.getClass().getDeclaredMethod("setStandardDeviationScore" + sort, String.class);
                                method.setAccessible(true);
                                method.invoke(satisfySurveyStatisticTotal, avgStandardDeviationScore.toString());
                            } catch (Exception e) {
                                throw new ControllerException("初始化统计报表标题失败");
                            }
                        }
                        sort++;
                        mapList.add(optionIdMap);
                    }
                }
            } else {
                //查询问卷统计分数列表
                List<QuerySatisfySurveyStatisticListVo.ClassifyScoreList> classifyScoreLists = odsSatisfyStatisticSettingDAO.queryClassifyScoreListByTitle(qo);
                if (CommonUtils.isNotEmpty(classifyScoreLists)) {
                    for (QuerySatisfySurveyStatisticListVo.ClassifyScoreList classifyScore : classifyScoreLists) {
                        //分类分数
                        BigDecimal score = classifyScore.getClassifyScore() == null ? BigDecimal.ZERO : new BigDecimal(classifyScore.getClassifyScore());
                        classifyScore.setClassifyScore(score.setScale(2, RoundingMode.HALF_UP).toString());
                        //分数标准差
                        BigDecimal standardDeviationScore = classifyScore.getStandardDeviationScore() == null ? BigDecimal.ZERO : new BigDecimal(classifyScore.getStandardDeviationScore());
                        classifyScore.setStandardDeviationScore(standardDeviationScore.setScale(2, RoundingMode.HALF_UP).toString());

                        QuerySatisfySurveyStatisticListVo.ClassifyScoreList classifyScoreList = odsSatisfyStatisticSettingDAO.queryMedianByTitleId(classifyScore.getOptionId());
                        if (null != classifyScoreList) {
                            BigDecimal median = classifyScoreList.getMedian() == null ? BigDecimal.ZERO : new BigDecimal(classifyScore.getClassifyScore());
                            classifyScore.setMedian(median.setScale(2, RoundingMode.HALF_UP).toString());
                        } else {
                            classifyScore.setMedian("0");
                        }
                        classifyScore.setSort(1);
                        titleOptionIdMap.put(classifyScore.getOptionId(), classifyScore);
                    }
                }
            }


            if(CommonUtils.isNotEmpty(simplePageInfo.getList())){
                //总调查人次
                BigDecimal totalSurveyPersonNumber = satisfySurveyStatisticTotal.getSurveyPersonNumber() == null ? BigDecimal.ZERO : new BigDecimal(satisfySurveyStatisticTotal.getSurveyPersonNumber());
                //总异常数
                BigDecimal totalAbnormalNumber = satisfySurveyStatisticTotal.getAbnormalNumber() == null ? BigDecimal.ZERO : new BigDecimal(satisfySurveyStatisticTotal.getAbnormalNumber());
                if(totalSurveyPersonNumber.intValue()>0){
                    //总异常占比
                    String totalAbnormalProportion = totalAbnormalNumber.multiply(new BigDecimal(100)).divide(totalSurveyPersonNumber,2,RoundingMode.HALF_UP).toString();
                    satisfySurveyStatisticTotal.setAbnormalProportion(totalAbnormalProportion);
                }else {
                    satisfySurveyStatisticTotal.setAbnormalProportion("0");
                }


                int sort=1;
                for (QuerySatisfySurveyStatisticListVo querySatisfySurveyStatisticListVo : simplePageInfo.getList()) {
                    //去除题目中的Html标签
                    if(CommonUtils.isNotEmpty(querySatisfySurveyStatisticListVo.getTypeName())){
                        querySatisfySurveyStatisticListVo.setTypeName(querySatisfySurveyStatisticListVo.getTypeName().replace("<p>","").replace("</p>",""));
                    }


                    if(totalSurveyPersonNumber.intValue()>0){
                        //占比
                        String proportion = new BigDecimal(querySatisfySurveyStatisticListVo.getSurveyPersonNumber())
                                .multiply(new BigDecimal(100)).divide(totalSurveyPersonNumber,2,RoundingMode.HALF_UP).toString();
                        querySatisfySurveyStatisticListVo.setProportion(proportion);
                    }else {
                        querySatisfySurveyStatisticListVo.setProportion("0");
                    }

                    if(totalAbnormalNumber.intValue()>0){
                        //异常占比
                        String abnormalProportion = new BigDecimal(querySatisfySurveyStatisticListVo.getAbnormalNumber())
                                .divide(totalAbnormalNumber,2,RoundingMode.HALF_UP).toString();
                        querySatisfySurveyStatisticListVo.setAbnormalProportion(abnormalProportion);
                    }else {
                        querySatisfySurveyStatisticListVo.setAbnormalProportion("0");
                    }

                    querySatisfySurveyStatisticListVo.setSort(String.valueOf(sort));
                    sort++;

                    if(!"0".equals(qo.getStatisticExtraId())){
                        for (Map<String, List<QuerySatisfySurveyStatisticListVo.ClassifyScoreList>> optionIdMap : mapList) {
                            List<QuerySatisfySurveyStatisticListVo.ClassifyScoreList> scoreLists = optionIdMap.get(querySatisfySurveyStatisticListVo.getOptionId());
                            if(CommonUtils.isNotEmpty(scoreLists)){
                                for (QuerySatisfySurveyStatisticListVo.ClassifyScoreList scoreList : scoreLists) {
                                    int sortCount = scoreList.getSort();
                                    Method method;
                                    try {
                                        method = querySatisfySurveyStatisticListVo.getClass().getDeclaredMethod("setScore" + sortCount, String.class);
                                        method.setAccessible(true);
                                        method.invoke(querySatisfySurveyStatisticListVo, scoreList.getClassifyScore());

                                        method = querySatisfySurveyStatisticListVo.getClass().getDeclaredMethod("setStandardDeviationScore" + sortCount, String.class);
                                        method.setAccessible(true);
                                        method.invoke(querySatisfySurveyStatisticListVo, scoreList.getStandardDeviationScore());
                                    } catch (Exception e) {
                                        throw new ControllerException("初始化统计报表标题失败");
                                    }
                                }
                            }
                        }
                    }else {
                        QuerySatisfySurveyStatisticListVo.ClassifyScoreList classifyScore = titleOptionIdMap.get(querySatisfySurveyStatisticListVo.getOptionId());
                        if(null != classifyScore){
                            querySatisfySurveyStatisticListVo.setMinScore(classifyScore.getMinScore());
                            querySatisfySurveyStatisticListVo.setMaxScore(classifyScore.getMaxScore());
                            querySatisfySurveyStatisticListVo.setStandardDeviationScore1(classifyScore.getStandardDeviationScore());
                            querySatisfySurveyStatisticListVo.setScore1(classifyScore.getClassifyScore());
                            querySatisfySurveyStatisticListVo.setMedian(classifyScore.getMedian());
                        }
                    }
                }
            }else {
                simplePageInfo.setList(new ArrayList<>());
            }

            if(!"0".equals(qo.getStatisticExtraId())){
                simplePageInfo.getList().add(simplePageInfo.getList().size(),satisfySurveyStatisticTotal);
            }

            return simplePageInfo;
        }catch (Exception e){
            e.printStackTrace();
            LOGGER.error("查询满意度问卷统计列表失败:" + e.getMessage());
            throw new ControllerException("查询满意度问卷统计列表失败");
        }
    }

    /**
     * @description: 导出exel
     * @author: chenJij@bsoft.com.cn
     * @date: 2022/7/29 17:54
     * @param: qo
     * @return: java.lang.String
     */
    @RpcService
    public String satisfySurveyStatisticExport(QuerySatisfySurveyStatisticListQo qo) throws ControllerException {
        List<String> titleList = queryTitleStringList(qo);
        SimplePageInfo<QuerySatisfySurveyStatisticListVo> simplePageInfo = querySatisfySurveyStatisticList(qo);
        byte[] data = SummarySatisfyStatisticExcelUtil.getExcelAsByteArray(qo,titleList,simplePageInfo.getList());
        return uploadExcel(data, "满意度问卷统计列表.xlsx");
    }

    private String uploadExcel(byte[] bytes, String fileName){
        int filesize = bytes.length;
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);

        UserRoleToken token = UserRoleToken.getCurrent();
        FileMetaEntity fileMeta = new FileMetaEntity();
        fileMeta.setLastModify(new Date());
        fileMeta.setUploadTime(new Date());
        fileMeta.setMode(31);
        fileMeta.setFileName(fileName);
        fileMeta.setContentType("application/octet-stream");
        fileMeta.setOwner(token.getUserId());
        fileMeta.setFileSize(filesize);
        fileMeta.setCatalog("export-file");
        String fileId = null;
        try {
            fileId = FileService.instance().upload(fileMeta, bis);
        } catch (Exception e) {
            LOGGER.error("文件上传失败", e);
        }
        return fileId;
    }
}